第 6 章 / Session

StoryCam 从“能生成”走向“稳定、可恢复、可并发”

日期:2026-04-28 类型:产品迭代 / 生成链路修复 / 架构改造 范围:Story World、Core Storyboard、资产图、恢复入口

本 session 围绕 StoryCam 的核心生成链路展开:先修复故事世界结构化输出不稳定的问题,再调整角色与场景资产的产品形态,随后把图片生成从同步等待升级为 Inference.sh 异步任务和前端轮询。

本 Session 摘要

生成链路从 OpenRouter 摸索到 DeepSeek strict tool 用户多次反馈“模型返回的故事格式不稳定”,最终将 Story World 文本生成切到 DeepSeek 官方 API strict function calling,并保留服务端 zod 校验与可诊断错误码。
Story World 的产品边界被重新定义 剧本不应像分镜;人物资产按关键人物数量生成,场景资产固定一个,但用 4-6 个小切图覆盖空间、光线、物件和动作区域。
视觉一致性成为资产生成的核心约束 角色和场景不再固定为日系动画或写实,而是共享由剧本推导出的 visualStyle;场景资产必须无人,避免后续视频混合时出现人物一致性问题。
核心分镜改造成 1/2/3 组,每组约 15 秒 用户选择的 8-9 秒、十几秒、15-20 秒被产品化为 1、2、3 组核心分镜,每组包含分镜脚本、主图和最多 8 张扩展图。
重启后资产丢失感通过恢复 API 解决 新增“自动恢复最近作品”和首页“最近项目”入口,恢复剧本、角色/场景资产、核心分镜和已生成图片,不依赖 localStorage。
图片生成从同步阻塞升级为异步并发 角色资产、场景资产、核心分镜主图、扩展分镜图都改为提交 Inference.sh async task,前端轮询 job 状态,单图失败不阻塞其他图。

时间线

01 / 角色资产提示词与图像服务配置 影响:确定资产图目标形态
用户原话

“这个板块期望生产的角色资产如图 2,你需要调整下生图的提示词。”

“请先把 STORYCAM_IMAGE_PROVIDER 设为 openrouter,并配置 OPENROUTER_IMAGE_MODEL。模型是:openai/gpt-5.4-image-2。”

Codex 总结

先按用户给出的角色资产参考图调整提示词,把角色图从普通剧照改成“角色设计参考板”。随后配置图像 provider,但上游 OpenRouter 图像模型出现不稳定、拒绝、格式不可靠等问题。

结果:图像能力进入真实 provider 调试阶段,也暴露出“只靠同步请求等待模型返回”不适合多图生成。

02 / Story World 文本结构化输出不稳定 影响:从兜底重试转向强约束输出
用户原话

“模型返回的故事格式不稳定,请再试一次。这个问题依然存在,需要从根上彻底解决这个问题,比如选择哪种输出格式来限制,或者需要换哪种模型来解决,同时你要给出输入和输出的 json 示例。”

“PLEASE IMPLEMENT THIS PLAN: Story World 稳定结构化输出改造计划。”

Codex 总结

判断问题不应继续靠“再试一次”解决,而要改变输出契约:Story World 文本生成切到 DeepSeek 官方 API,使用 deepseek-v4-pro + Strict Function Calling Beta,强制调用 submit_story_world,模型只产内容,服务端补齐 id、session、版本和状态。

结果:错误从“故事格式不稳定”变成可诊断的工具调用缺失、JSON 解析失败、schema 校验失败、provider 超时等状态。

03 / Core Storyboard 重新定义为真实生成阶段 影响:把片长选择转成分镜组数量
用户原话

“当用户从 /storycam/story-world 生产了剧本、角色资产、场景资产,然后选择 8-9 秒、十几秒或 15-20 秒,这三种选择分别对应一组、两组、三组分镜。”

“点击一个分镜图,会以浮窗的形式打开分镜扩展画布页面,而不需要跳到一个新的页面。”

Codex 总结

将 Core Storyboard 改成真实生成阶段:Story World 确认后,根据用户选择生成 1/2/3 个核心分镜组。每组约 15 秒,包含分镜脚本、主分镜图和最多 8 张扩展图。扩展画布作为 modal overlay 打开,不改变主流程 URL。

结果:核心分镜组成为后续视频片段生成单位,而扩展图是辅助画布,不默认触发视频生成。

04 / 重启后内容丢失感 影响:建立账号级恢复机制
用户原话

“现在还有个问题,就是没有保存用户已经生成的剧本、角色资产、场景资产等,致使重启服务后,所有都需要重新再试试来一遍。”

“应该在首页……加一个‘最近项目’入口,便于用户从首页能恢复到之前做过的具体项目。”

Codex 总结

恢复策略确定为“Supabase 数据库和私有 Storage 是唯一真实来源”。新增当前 session 恢复 API、指定 session 恢复 API、最近项目摘要 API;首页不自动跳转,只提供最近项目入口,后续流程页刷新或重启后仍自动恢复。

结果:StoryCam 从一次性生成 demo 变成可继续创作的账号项目流。

05 / 人物数量与单一多切图场景资产 影响:资产体系从“多场景卡”变成“一个场景板”
用户原话

“人物资产可以根据剧本里的人物数量来定,但场景资产固定一个。”

“生成的唯一一个场景资产要像图里所示的,在一张图里足够的小切图来满足根据剧本所需的场景资产。”

Codex 总结

角色资产改为只生成主角级或关键对手戏人物,最多 3 个;场景资产固定 1 个,并新增 scenePanels,用 4-6 个 panel 描述主场景、广角、中景、细节、光线或俯视等素材需求。

结果:场景图提示词改为 16:9 多面板环境资产板,满足后续分镜需要,同时避免生成多个割裂的地点资产。

06 / UI 反馈驱动布局修复 影响:确认页从功能可用走向可讲述
用户原话

“场景资产这页有问题,没有办法下拉,也没有生图按钮。”

“左侧进度条去掉‘输入创意’步骤,改为左上角的 logo 点击返回首页。”

“图中左上角红框‘步骤 2’去掉,角色资产红框出来的布局不对,右边有很大空白。”

Codex 总结

围绕 Story World Review 做了一组前端修正:资产 modal 可滚动、生成按钮可见;logo 返回首页;进度条移除“输入创意”;标题上方步骤 pill 去掉;角色资产卡改为自适应铺开;底部 dock 缩小为更轻的居中浮条。

结果:页面更接近“导演工作台”的确认体验,而不是堆叠表单。

07 / 视觉风格与无人场景资产 影响:解决角色和场景风格不一致
用户原话

“角色资产这一次生成的偏动漫的,但是场景资产偏真实场景,这两个不协调。”

“场景资产里好几处含有人物,场景资产是不应该有人物的,要不后面生成视频和角色资产混合后会有一致性的问题。”

“角色资产是要根据剧本生成风格,如果是真人风格,那场景资产也要协同,不能什么时候角色都是漫画风格。”

Codex 总结

新增共享视觉锚点 script.visualStyle。角色图和场景图都使用同一风格描述,不再固定日系动画或写实。场景 prompt 增加强约束:无人、无剪影、无反射人物、无身体局部、无群众。

结果:视觉一致性从“提示词感觉”上升为 Story World 输出的一部分,后续视频生成也更容易保持资产一致。

08 / 剧本和分镜边界重新校准 影响:避免 Story World 过早进入导演 shot table
用户原话

“storycam/story-world 板块里生成的剧本怎么感觉像是分镜里,有点不对,这块是剧本,下个板块才会根据剧本生成分镜脚本,具体技巧参考 docs/references/shanyin-director-master。”

Codex 总结

明确 Story World 阶段只应生成剧本级故事材料、人物和场景资产,不输出镜头编号、机位、景别、剪辑节奏等分镜脚本信息。Core Storyboard 才负责将剧本转译成可拍摄的分镜组。

结果:产品层级更清楚:普通用户先确认故事世界,再由系统进入导演式拆解。

09 / 2 组和 3 组核心分镜接口 500 影响:同步多图生成被判定为架构问题
用户原话

“现在选择 2 组和 3 组生成核心分镜的时候,接口请求都是 500,只有 1 组时能正常调用。”

“点击‘对,生成核心分镜’后按钮应该变成一个动态的状态,使得感知在执行。底栏的‘重新生成’和‘删除这个故事’两个按钮交互不需要,可以去掉。”

Codex 总结

根因判断:接口请求内同步等待多张图片生成,2/3 组时容易超时或上游失败,导致整个 storyboard 请求 500。UI 同时缺少生成中的明确反馈。

结果:底栏只保留组数选择和主 CTA;CTA 生成中禁用并显示“正在生成核心分镜”。更重要的是,为异步图片任务改造铺路。

10 / Inference.sh 官方 skill、CLI、SDK 沉淀与异步化 影响:多图生成进入可并发架构
用户原话

“看看官方 skills、cli、sdk 等操作,将现在板块里生图的操作改成可并发、异步的,比如角色资产、场景资产就是可以多线程并发,比如生成多组核心分镜也是要并发生多图。”

“Inference.sh 的一些官方核心内容要沉淀 docs,便于后面开发注意。”

Codex 总结

查阅 Inference.sh 官方 skills 仓库后,抽取 SDK 和 CLI 关键约定:client.run(..., { wait:false }) 提交任务,client.getTask(taskId) 查询状态;CLI 对应 belt app run --no-waitbelt task get;图片输出通常读取 output.images

结果:实现了 Inference.sh async image provider、图片 job 服务、Story World 批量资产图接口、Storyboard/Expansion 并发提交、前端轮询替换图片,并新增官方知识文档。

关键时刻

关键时刻 1:结构化输出不能靠“再试一次”

问题:Story World 文本格式不稳定,导致前端只能提示“模型返回的故事格式不稳定”。

为什么重要:剧本、角色资产、场景资产是后续所有生成的源头,如果源头 schema 不稳定,后续恢复、分镜和视频都会被污染。

处理:切到 DeepSeek 官方 strict function calling,强制工具调用,并把错误拆成 tool call 缺失、arguments 非 JSON、schema 不匹配、provider 失败等可诊断状态。

关键时刻 2:场景资产从“多张场景”变成“一个多切图场景板”

问题:剧本可能需要多个角度和物件细节,但产品不希望生成多个割裂的场景资产。

为什么重要:StoryCam 面向普通用户,确认资产要简单;同时视频生成需要足够多的环境参考。

处理:固定只生成一个 scene_asset,内部新增 4-6 个 scenePanels,图像提示词生成一张 16:9 环境资产板。

关键时刻 3:视觉风格被提升为 Story World 的共享字段

问题:角色资产偏动漫,场景资产偏真实,后续合成会产生风格和人物一致性问题。

为什么重要:StoryCam 不是固定风格的短剧工具,用户可能要韩剧、私人回忆、漫画、绘本或胶片感。

处理:新增 script.visualStyle,角色图和场景图共用这个风格锚点;场景图明确禁止出现任何人物、剪影、反射或身体局部。

关键时刻 4:2/3 组核心分镜 500 的根因是同步多图

问题:1 组可以生成,2/3 组接口直接 500。

为什么重要:核心分镜是从故事世界进入视频生产的关键关口,如果多组不可用,产品的 30 秒和 45 秒路径就断了。

处理:把图片生成从请求内同步等待改为 Inference.sh 异步任务;API 先返回分镜文本和 generating 图片状态,前端轮询 job,完成后替换为 signed URL。

关键时刻 5:恢复机制让 StoryCam 从 demo 变成项目工作台

问题:服务重启或刷新后,已生成的剧本、资产和分镜丢失,用户必须重来。

为什么重要:AI 生成过程成本高、耗时长,不可恢复会破坏用户信任。

处理:使用 Supabase 数据和私有 Storage 作为唯一真实来源,增加“自动恢复最新”和“最近项目”入口,不把私密素材放进 localStorage。

工程证据

PR / Commit
本 session 未产生可确认的 PR 或 commit 记录。
关键文件
src/server/storycam/imageGenerationJobService.tssrc/lib/providers/inferenceSh/imageProvider.tssrc/server/storycam/storyboardService.tssrc/server/storycam/expansionService.tssrc/server/storycam/storyWorldAssetImageService.tssrc/components/storycam/StoryWorldReview.tsxsrc/components/storycam/StoryCamWorkspace.tsx
新增接口
POST /api/story-world/assets/generate-images;复用并增强 GET /api/generation-jobs/:id 作为图片 job 状态查询入口。
数据库变更
supabase/migrations/20260428143000_storycam_image_generation_jobs.sql 扩展 generation_jobs.type,新增 story_world_asset_imagestoryboard_imageexpanded_storyboard_image
文档沉淀
docs/references/inference-sh.md 记录 Inference.sh SDK、CLI、task status、错误映射、图片输出和 StoryCam 异步管线;docs/references/providers.md 增加链接和异步说明。
验证命令
pnpm typecheck passed; pnpm lint passed; pnpm exec vitest run src/lib/providers/inferenceSh/imageProvider.test.ts tests/api/storyboard.test.ts tests/api/expansion.test.ts passed,3 个测试文件、13 个测试通过。
安全处理
不记录 prompt、API key、provider image URI、signed URL、私密输入或原始 provider payload;图片完成后才由服务端下载并写入私有 Storage。
未确认
本 session 未记录完整 E2E 运行结果;真实 Inference.sh 线上 smoke 结果未在聊天中确认。

对外讲解用总结

这一轮开发把 StoryCam 的核心生成体验从“单次同步调用”推进成了更接近真实产品的工作流。前半段解决的是生成内容是否可信:Story World 必须稳定地产出剧本、关键人物和唯一场景资产,且剧本不能提前变成分镜。中段解决的是资产是否可用:角色数量要跟剧本一致,场景资产要用一张多切图参考板覆盖空间需求,角色和场景必须共享视觉风格,场景不能混入人物。后半段解决的是工程可承载性:多张图片不再阻塞同一个请求,而是通过 Inference.sh 异步任务并发生成,前端轮询展示进度,失败的单张图不会拖垮整个故事或分镜组。

这一步连接了前面的“故事世界生成”和后面的“视频片段生成”:只有当剧本、资产、分镜和图片状态都能被保存、恢复、并发推进,StoryCam 才能从一个 AI 生成 demo 变成用户可以反复回到其中继续创作的导演工作台。

后续事项